package com.wjk.kylin.mall.auth.exception;

import com.wjk.kylin.mall.common.core.dto.base.BaseOutDTO;
import com.wjk.kylin.mall.common.core.exception.BaseError;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author wangjkui
 * @description 全局的的异常拦截器（拦截所有的控制器）（带有@RequestMapping注解的方法上都会拦截）
 * @date 2020/5/22
 */
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
@RestControllerAdvice
public class AuthExceptionHandler{

    /**
     * 用户不存在
     *
     * @param e
     * @return
     */
    @ExceptionHandler(UsernameNotFoundException.class)
    public BaseOutDTO handleUsernameNotFoundException(UsernameNotFoundException e) {
        log.error("用户不存在:{}", e.getMessage(), e);
        return BaseOutDTO.error(BaseError.USER_NOT_EXIST);
    }

    /**
     * 用户名和密码异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(InvalidGrantException.class)
    public BaseOutDTO handleInvalidGrantException(InvalidGrantException e) {
        log.error("用户名和密码异常:{}", e.getMessage(), e);
        return BaseOutDTO.error(BaseError.USERNAME_OR_PASSWORD_ERROR);
    }

    /**
     * 账户异常禁用
     *
     * @param e
     * @return
     */
    @ExceptionHandler({DisabledException.class})
    public BaseOutDTO handleDisabledException(DisabledException e) {
        log.error("账户异常禁用异常:{}", e.getMessage(), e);
        return BaseOutDTO.error(BaseError.ACCOUNT_DISABLED);
    }


    /**
     * 账户异常锁定
     *
     * @param e
     * @return
     */
    @ExceptionHandler({LockedException.class})
    public BaseOutDTO handleLockedException(LockedException e) {
        log.error("账户异常锁定异常:{}", e.getMessage(), e);
        return BaseOutDTO.error(BaseError.ACCOUNT_LOCKED);
    }

    /**
     * 账户异常过期
     *
     * @param e
     * @return
     */
    @ExceptionHandler({AccountExpiredException.class})
    public BaseOutDTO handleAccountExpiredException(AccountExpiredException e) {
        log.error("账户异常过期异常:{}", e.getMessage(), e);
        return BaseOutDTO.error(BaseError.ACCOUNT_EXPIRED);
    }

    /**
     * 账户异常(禁用、锁定、过期)
     *
     * @param e
     * @return
     */
    @ExceptionHandler({InternalAuthenticationServiceException.class})
    public BaseOutDTO handleInternalAuthenticationServiceException(InternalAuthenticationServiceException e) {
        log.error("账户异常(禁用、锁定、过期)异常:{}", e.getMessage(), e);
        return BaseOutDTO.error(BaseError.ACCOUNT_EXPIRED_LOCKED_EXPIRED.getCode(),e.getMessage());
    }

    /**
     * OAuth2Exception
     * @param e
     * @return
     */
    @ExceptionHandler(value = OAuth2Exception.class)
    public BaseOutDTO handleOAuth2Exception(OAuth2Exception e) {
        log.error("OAuth2未知异常:{}", e.getMessage(), e);
        return BaseOutDTO.error(BaseError.ACCOUNT_EXPIRED_LOCKED_EXPIRED);
    }

    /**
     * 用户未查询到所属角色
     *
     * @param e
     * @return
     */
    @ExceptionHandler(UserNotFoundRoleException.class)
    public BaseOutDTO handleUserNotFoundRoleException(UserNotFoundRoleException e) {
        log.error("用户未查询到所属角色:{}", e.getMessage(), e);
        return BaseOutDTO.error(BaseError.ACCOUNT_NOT_FOUND_ROLE);
    }

}
